package org.hhttp.request;

import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

import org.hhttp.common.StringUtils;
import org.hhttp.cookie.DefaultCookie;
import org.hhttp.core.Constants;
import org.hhttp.core.Cookie;
import org.hhttp.core.Request;
import org.hhttp.core.Session;
import org.hhttp.session.MemcachedSession;

public class DefaultRequest implements Request{
	
	private static final long serialVersionUID = -3935974170995766376L;
	
	private String method;
	private URI uri;
	private String host;
	private String http_version;
	private Map<String,String> params = new HashMap<String,String>();
	private Session session;
	
	
	private String sessionId;
	private Cookie cookie;
	
	private Cookie setCookie;
	
	InputStream inputStream;  
	
	public DefaultRequest(){
		this.cookie = new DefaultCookie() ;
		this.setCookie = new DefaultCookie() ;
		
		this.session = new MemcachedSession();
	}

	public void init(){
		try {
			StringBuilder sb = new StringBuilder();
			byte [] b=new byte[1024];
			
			int len = 0;
			logger.debug("inputStream size :" + inputStream.available());
			while(inputStream.available() > 0){
				len=inputStream.read(b);
				if(len <= 0){
					break;
				}
				sb.append(new String(b)); 
			}
			logger.debug("inputStream read end :" + sb);
			initHeader(sb.toString());
			
		} catch (Exception e) {
			logger.error("request init error " + e);
		}
	}
	
	public void initHeader(String header) throws Exception{
		
        String cookies = null ;
        String[] vs = header.split("\n");
		String[] v1 = vs[0].split(" ");
		if(v1.length != 3){
			logger.warn("request header msg " + header);
			throw new Exception("request header error");
		}
		this.method = v1[0];
		this.uri = URI.create(v1[1]);
		this.http_version = v1[2];
		
		logger.debug("request init param start");
		//init  params
		String query = uri.getQuery();
		if(!StringUtils.isBlank(query)){
			String[] ps = query.split("&");
			for(int i=0;i<ps.length;i++){
				String[] pv = ps[i].split("=");
				if(pv.length == 2 && !StringUtils.isBlank(pv[1])){
					params.put(pv[0], pv[1]);
				}
			}
		}
		logger.debug("request init header start");
		//init header
		for(int i=1;i<vs.length;i++){
			String str = vs[i];
			if(StringUtils.isBlank(str)){
				continue;
			}
			if(str.startsWith("Host:")){
				setHost(str);
			}else if(str.startsWith("Cookie:")){
				cookies = str;
				
			}
		}
		logger.debug("request init cookies start");
		//init cookie
		initCookie(cookies);
		
	}
	
	public void initCookie(String cookieStr) {
		if(cookieStr != null){
			String str = cookieStr;
			int sp = str.indexOf(": ");
			if(sp == -1){
				return;
			}
			str = str.substring(sp + 2, str.length());
			String [] ps = str.split(";");
			for(int i=0;i<ps.length;i++){
				String[] cookies = ps[i].split("=");
				if(cookies.length == 2 && !StringUtils.isBlank(cookies[1])){
					cookie.setCookie(cookies[0], cookies[1]);
				}
			}
		}
		
		//session Id
		Object temo = cookie.getCookie(Constants.SESSION_ID);
		if(temo == null){
			sessionId = "zz" + System.currentTimeMillis();
			setCookie.setCookie(Constants.SESSION_ID, sessionId);
		}else{
			sessionId = temo.toString();
		}
		this.setSessionId(sessionId);
	}
	

	public InputStream getInputStream() {
		return inputStream;
	}

	public String getMethod() {
		return method;
	}

	public URI getUri() {
		return uri;
	}

	public String getHost() {
		return host;
	}

	private void setHost(String str) {
		int sp = str.indexOf(": ");
		if(sp != -1){
			this.host = str.substring(sp + 2, str.length());
		}
	}

	public Map<String, String> getParams() {
		return params;
	}
	public Session getSession() {
		return session;
	}

	public String getHttpVersion() {
		return http_version;
	}
	
	@Override
	public Object getParam(String key) {
		return this.params.get(key);
	}

	@Override
	public void reset() {
		this.method = null;
		this.uri = null;
		this.host = null;
		this.http_version = null;
		if(this.params != null){
			this.params.clear();
		}
		this.cookie.reset();
		this.setCookie.reset();
	}
	
	public static void main(String [] srgs) {
		URI uri = URI.create("http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html?");
		System.out.println(uri.getHost());
		
		System.out.println(uri.getScheme());
		System.out.println(uri.getPort());
		System.out.println(uri.getQuery());
		System.out.println(uri.getUserInfo());
		System.out.println(uri.toString());
		System.out.println(uri.getSchemeSpecificPart());
		System.out.println(uri.getRawPath());
		System.out.println(uri.getQuery());
		System.out.println(uri.getFragment());
		
		String aa = "Host: localhost:12345";
		int sp = aa.indexOf(": ");
		System.out.println(aa.substring(0, sp));
		System.out.println(aa.substring(sp + 2, aa.length()));
	}

	@Override
	public void setSession(Session session) {
		this.session = session;
	}

	@Override
	public Cookie getCookie() {
		return cookie;
	}

	@Override
	public void setCookie(Cookie cookie) {
		this.cookie = cookie;
		
	}

	@Override
	public void setSetCookie(Cookie setCookie) {
		this.setCookie = setCookie;
	}

	@Override
	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}

	@Override
	public String getSessionId() {
		return this.sessionId;
	}

	@Override
	public Cookie getSetCookie() {
		return this.setCookie;
	}

	private void setSessionId(String sessionId) {
		this.sessionId = sessionId;
		this.session.setSessionId(sessionId);
	}

}
